import { appendFile } from 'fs';
import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
import MyPlugin from './main1';

import { MyPluginSettings, DEFAULT_SETTINGS, MySettingTab } from "./setting"
import DefaultImageUpload from './uploader/DefaultImageUploader';
import ImageUploader from './uploader/ImageUpload';
import { existsSync, mkdirSync, writeFileSync } from "fs";

// 插件主功能设置！！
export default class AutoUploadPlugin extends Plugin {
	settings: MyPluginSettings;
	imageUpload: ImageUploader


	// 异步：加载插件
	async onload() {
		await this.loadSettings();
		await this.loadImageUpload();

		// // 添加一条命令
		// this.addCommand({
		// 	id: 'simple-plugin-demo-command1',
		// 	name: '简单插件命令示例',
		// 	callback: () => {
		// 		new Notice(this.settings.welcomeStr);
		// 		new SampleModal(this.app).open();
		// 	}
		// });

		// 添加插件设置面板
		this.addSettingTab(new MySettingTab(this.app, this));
		this.registerEvent(
			this.app.workspace.on("editor-paste", this.customPasteEventCallback)
		);
	}

	// 卸载插件
	onunload() {

	}

	// 异步：加载设置
	async loadSettings() {
		this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
	}

	async loadImageUpload() {
		this.imageUpload = new DefaultImageUpload();
	}

	// 异步：保存设置
	async saveSettings() {
		await this.saveData(this.settings);
	}

	private checkUploadAddress(): boolean {
		return typeof this.settings.uploadAddress != "undefined"
			&& this.settings.uploadAddress != null && this.settings.uploadAddress != ""
	}


	private customPasteEventCallback = async (
		e: ClipboardEvent,
		_: Editor,
		markdownView: MarkdownView
	) => {

		// writeFileSync(path, buffer);
		if (!this.checkUploadAddress()) {
			AutoUploadPlugin.showUnconfiguredPluginNotice();
			return;
		}

		const { files } = e.clipboardData;
		if (files.length === 0 || !files[0].type.startsWith("image")) {
			return;
		}

		e.preventDefault();


		for (let i = 0; i < files.length; i += 1) {
			this.uploadFileAndEmbedImgurImage(files[i]).catch(() => {

			});
		}
	};

	private async uploadFileAndEmbedImgurImage(file: File) {
		const pasteId = (Math.random() + 1).toString(36).substr(2, 5);
		this.insertTemporaryText(pasteId);
		let imgUrl: string;
		try {
			imgUrl = await this.imageUpload.upload(file, this.settings.uploadAddress);
		} catch (e) {
			// eslint-disable-next-line no-console
			console.error("Failed imgur request: ", e);
			this.handleFailedUpload(
				pasteId,
				"⚠️Imgur upload failed, check dev console"
			);
			throw e;
		}
		this.embedMarkDownImage(pasteId, imgUrl);
	}

	private insertTemporaryText(pasteId: string) {
		const progressText = AutoUploadPlugin.progressTextFor(pasteId);
		this.getEditor().replaceSelection(`${progressText}\n`);
	}

	private static progressTextFor(id: string) {
		return `![Uploading file...${id}]()`;
	}

	private embedMarkDownImage(pasteId: string, imageUrl: string) {
		const progressText = AutoUploadPlugin.progressTextFor(pasteId);
		const markDownImage = `![](${imageUrl})`;

		AutoUploadPlugin.replaceFirstOccurrence(
			this.getEditor(),
			progressText,
			markDownImage
		);
	}

	private handleFailedUpload(pasteId: string, message: string) {
		const progressText = AutoUploadPlugin.progressTextFor(pasteId);
		AutoUploadPlugin.replaceFirstOccurrence(
			this.getEditor(),
			progressText,
			`<!--${message}-->`
		);
	}

	private getEditor(): Editor {
		const mdView = this.app.workspace.activeLeaf.view as MarkdownView;
		return mdView.editor;
	}

	private static replaceFirstOccurrence(
		editor: Editor,
		target: string,
		replacement: string
	) {
		const lines = editor.getValue().split("\n");
		for (let i = 0; i < lines.length; i += 1) {
			const ch = lines[i].indexOf(target);
			if (ch !== -1) {
				const from = { line: i, ch };
				const to = { line: i, ch: ch + target.length };
				editor.replaceRange(replacement, from, to);
				break;
			}
		}
	}


	private static showUnconfiguredPluginNotice() {
		const fiveSecondsMillis = 5_000;
		// eslint-disable-next-line no-new
		new Notice(
			"⚠️ Please configure upload address",
			fiveSecondsMillis
		);
	}
}



